#ifndef DIARYTOOL_SQL_SQLITE3_DRIVER_HPP
#define DIARYTOOL_SQL_SQLITE3_DRIVER_HPP

#include "sql/sql_driver.hpp"

struct Sqlite3DriverData;
class Sqlite3Driver : public ISqlDriver {
    Sqlite3DriverData* d;
public:
    Sqlite3Driver();
    ~Sqlite3Driver();

    void InitConnection() override;

    bool IsConfigured() override;

    void InitTables() const override;

    bool KeepAlive() override;

    std::vector<Tag> AllTags() const override;

    Tag NewTag(const std::string& tag_name, uint32_t color, uint32_t level) const override;

    bool DeleteTag(int tag_id) const override;

    bool UpdateTag(Tag& tag) const override;

    std::vector<RedMineActivity> AllRedMineActivities() const override;

    bool DeleteRedMineActivity(int act_id) const override;

    bool UpdateRedMineActivity(RedMineActivity& tag) const override;

    std::vector<RedMineIssue> AllRedMineIssues() const override;

    bool DeleteRedMineIssue(int issue_id) const override;

    bool UpdateRedMineIssue(RedMineIssue& issue) const override;

    WorkItem NewWorkItem(double hour, const std::string& comment, const std::string& note,
        const std::string& create_date, int32_t priority) const override;

    bool SetWorkItemActivity(int work_id, int act_id) const override;

    bool SetWorkItemIssue(int work_id, int issue_id) const override;

    bool SetWorkItemUploaded(int work_id) const override;

    bool UpdateWorkItem(WorkItem& item) const override;

    bool DeleteWorkItem(int work_id) const override;

    bool AddItemTag(int work_id, int tag_id) const override;

    bool DeleteItemTag(int work_id, int tag_id) const override;

    bool ClearItemTags(int work_id) const override;

    std::vector<Tag> AllWorkItemTags(int work_id) override;

    std::vector<std::string> GetYearList() const override;

    std::vector<std::string> GetMonthList(const std::string& year) const override;

    std::vector<std::string> GetDayList(const std::string& year_and_month) const override;

    std::vector<WorkItem> GetDailyItems(const std::string& date) const override;

    std::vector<WorkItem> GetItemsByTagAndDate(const std::string& date_start, const std::string& date_end, int tag_id_l1, int tag_id_l2) const override;

    StatisticsResult GetStatisticsResult(const std::string& date_start, const std::string& date_end) const override;

    StatisticsResult GetStatisticsResult() const override;

    StatisticsResult GetStatisticsResult(const std::string &date_start, const std::string &date_end, int tag_id) const override;

    void MigrateTables(int32_t old_version) const override;

    [[nodiscard]] int32_t GetDataVersion() const override;

    void                   InitPreparedStatements() const override;
    WorkTask               NewTask (std::string task_desc, const std::string &create_date, uint32_t color) override;
    bool                   UpdateTask (const WorkTask &task) override;
    bool                   DeleteTask (const WorkTask &task) override;
    bool                   SetTaskStatus (WorkTask &task, TaskStatus status) override;
    std::vector<WorkTask>  GetTasks () const override;
    WorkTask               GetCurrentTask () const override;
    void                   ClearActiveTask() const override;
    TimeEntry              NewTimeEntry (int32_t task_id, const std::string &start_date_time) override;
    bool                   UpdateTimeEntry (TimeEntry &entry, const std::string &end_time, int32_t duration) override;
    void                   MarkTimeEntryAsExported(TimeEntry &entry) const override;
    std::vector<TimeEntry> GetTimeEntries (int32_t task_id, const std::string &date_beg, const std::string &date_end) override;
    std::vector<TimeEntry> GetTimeEntries(const std::string &date_beg, const std::string &date_end) const override;
    TimeEntry              GetCurrentTimeEntry(int32_t entry_id) const override;
};

const DriverFactory* GetSqlite3Driver();

#endif // DIARYTOOL_SQL_SQLITE3_DRIVER_HPP
